<?php
/**
 * file模板文件分发器
 * Created by <xinxin.deng>.
 * Author: xinxin.deng
 * Date: 2018/11/12 11:47
 */
set_time_limit(0);
include_once dirname(dirname(dirname(dirname(dirname(__FILE__)))))."/common.php";
include_once dirname(__FILE__)."/soap/client.php";
\ns_core\m_load::load("ns_model.delivery.file_delivery_explain");
class file_delivery extends \ns_model\delivery\file_delivery_explain
{
    /**
     * CDN注入统一解释器入口
     */
    public function explain()
    {
        $fuc_name = (string)$this->get_c2_type();
        if (empty($fuc_name))
        {
            return $this->write_log_return('C2类型参数为空', NS_CDS_FAIL);
        }
        return $this->save_exec_log($this->$fuc_name());
    }

    /**
     * CDN注入统一发送器入口
     * 按项目进行自定义发送处理
     * @param $data array(
     *       'nns_task_type' =>类型,
     *       'nns_action' => 行为动作，
     *       'nns_content' => 注入XML内容
     * );
     * @return array('ret','reason');
     */
    public function execute($data)
    {
        if (empty($data['nns_addr']) || empty($data['CSPID']) || empty($data['LSPID'])
        || strlen($data['nns_addr']) < 1 || strlen($data['CSPID']) < 1 || strlen($data['LSPID']) < 1)
        {
            return $this->write_log_return('参数数据为空,目标地址：' . htmlspecialchars($data['nns_addr'])
                . 'CSPID:' . $data['CSPID'] . 'LSPID:' . $data['LSPID'], NS_CDS_FAIL);
        }

        $cdn_code = NS_CDS_CDN_LOADING;
        //生成CDN工单唯一ID
        $data['nns_id'] = $this->get_guid();
        $task = $this->save_execute_import_content($data['nns_content'], $this->arr_sp_config['xml_ftp']);
        if ($task['ret'] != 0)
        {
            $this->write_log_return($task['reason'], NS_CDS_FAIL);
            return $task;
        }
        $local_url = $task['data_info']['base_dir'];
        $ftp_url = $task['data_info']['ftp_url'];
        try
        {
            $client_re = client::ExecCmd($data['nns_id'], $ftp_url, $data['nns_addr'], $data['CSPID'], $data['LSPID']);
            $import_code = isset($client_re->Result) ? $client_re->Result : $client_re->result;
            $import_code = ($import_code === null) ? NS_CDS_CDN_NOTIFY_SUCCE : $import_code;
            $reason = $client_re->ErrorDescription;
            if ($import_code != NS_CDS_CDN_NOTIFY_SUCCE)
            {
                $cdn_code = NS_CDS_CDN_FAIL;
                $reason = '发送cdn失败' . $reason;
            }

            $this->write_log_return($reason, $cdn_code);
        } catch (Exception $e)
        {
            $import_code = NS_CDS_CDN_FAIL;
            $cdn_code = NS_CDS_CDN_FAIL;
            $reason = '发送cdn抛出异常,发送CDN失败,请联系工作人员';
            $this->write_log_return($reason, $cdn_code);
        }
        $data['nns_url'] = $local_url;
        $data['nns_result'] = $import_code;
        $data['nns_send_time'] = date("Y-m-d H:i:s");
        $data['nns_result_fail_reason'] = $reason . '目标地址为[' . $data['nns_addr'] . ']';
        $data['nns_task_id'] = $this->get_c2_info('id');
        $data['nns_task_name'] = $this->get_c2_info('name');

        //特殊定制将目标地址存入扩展信息--xinxin.deng 2018/11/13 15:06
        $data['nns_ex_info'] = json_encode($data['nns_addr']);

        /**
         * $data
         * array(
         *            'nns_task_type'=>'Series',
         *            'nns_task_id'=> 'C2任務ID',
         *            'nns_task_name'=> '任務名稱',
         *            'nns_action'=> '行為動作',
         *            'nns_result' => 0 成功 其他失敗
         *            'nns_result_fail_reason' => 發送失敗原因描述
         *      )
         * */
        $build_c2 = $this->build_c2_log($data);
        if ($build_c2['ret'] != NS_CDS_SUCCE)
        {
            return $this->write_log_return($build_c2['reason'], $build_c2['ret']);
        }
        $this->c2_info['nns_addr'] = $data['nns_addr'];

        return $this->is_ok($cdn_code, $reason);
    }

    /**
     * @description:调用进行反馈
     * @author:xinxin.deng
     * @date: 2018/3/6 11:33
     * @param $c2_correlate_id
     * @param $code
     * @param $result_url
     * @return array
     */
    public function notify($c2_correlate_id, $code, $result_url)
    {
        //$reason = '注入CDN成功';
        $notify_result = 'CDN反馈成功';
        if (!empty($result_url))
        {
            //获取到xml内容
            //$notify_result = @file_get_contents($result_url);
            $notify = $this->save_ftp_content($result_url);
            $this->write_log_return('获取到的数据为:' . var_export($notify), true);
            if (!$notify)
            {
                $reason = '发送至CDN成功,但是下载CDN反馈的远程文件失败' . $result_url;
                $notify_result = 'CDN反馈成功但是,' . $reason;
                $this->write_log_return('下载CDN反馈的远程文件失败' . $result_url, NS_CDS_FAIL);
            }
            else
            {
                //解析得到xml反馈的原因
                $ar_result = $this->notify_content_to_arr($notify);
                $this->write_log_return('解析到的数据为:' . var_export($ar_result), true);
                if ($ar_result['ret'] != 0)
                {
                    $reason = '发送至CDN成功但是,' . $ar_result['reason'];
                    $notify_result = 'CDN反馈成功但是,' . $ar_result['reason'];
                    $this->write_log_return($ar_result['reason'], NS_CDS_FAIL);
                } else
                {
                    if ($ar_result['data_info']['Result'] != 0)
                    {
                        $reason = '发送至CDN成功,但注入失败,反馈消息为：' . $ar_result['data_info']['Description'];
                        $notify_result = 'CDN反馈成功但是,注入失败,反馈消息为:' . $ar_result['data_info']['Description'];
                        $this->write_log_return($reason, NS_CDS_FAIL);
                    }
                }
            }
        }
        return $this->is_notify_ok($c2_correlate_id, $code, $notify_result, $notify);
    }


    private function epgfile()
    {
        if ($this->get_c2_info("action") === NS_CDS_DELETE)
        {
            $action = "DELETE";
        } else
        {
            $action = "REGIST-UPDATE";
        }
        $epg_file_set_info = $this->get_epg_file_set_info();
        $epg_file_info = $this->get_epg_file_info();

        if (empty($epg_file_set_info) || !is_array($epg_file_set_info))
        {
            return $this->write_log_return("C2任务epgfileset数据错误，执行注入CDN失败", NS_CDS_FAIL);
        }
        if (empty($epg_file_set_info['nns_url']) || strlen($epg_file_set_info['nns_url']) < 1)
        {
            return $this->write_log_return("C2任务epgfileset数据目标地址错误，执行注入CDN失败", NS_CDS_FAIL);
        }
        $addr_arr = array_unique(explode(',', $epg_file_set_info['nns_url']));
        if (!is_array($addr_arr) || count($addr_arr) < 1)
        {
            return $this->write_log_return("C2任务epgfileset数据目标地址错误，执行注入CDN失败", NS_CDS_FAIL);
        }
        if (empty($epg_file_info) || !is_array($epg_file_info))
        {
            return $this->write_log_return("C2任务epgfile数据错误，执行注入CDN失败", NS_CDS_FAIL);
        }

        $show_time = (!isset($epg_file_set_info['nns_show_time']) || $epg_file_set_info['nns_show_time'] == '0000-00-00 00:00:00')
            ?  '' : date('YmdHis' , strtotime($epg_file_set_info['nns_show_time']));
        $xml_str = '<?xml version="1.0" encoding="UTF-8"?><ADI xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" BizDomain="2" Priority="1">';
        $xml_str .= '<Objects>';
        //EPGFileSet
        $xml_str .= '<Object ElementType="EPGFileSet" ID="' . $epg_file_set_info['nns_import_id'] . '" >';
        $xml_str .= '<Property Name="EPGGroup">' . $epg_file_set_info['nns_group'] . '</Property>';//文件分组
        $xml_str .= '<Property Name="SystemFile">' . $epg_file_set_info['nns_system_file'] . '</Property>';//是否为系统文件，0否 1是；媒体文件URL,ftp://username:password@ip:port/...  标准FTP协议
        $xml_str .= '<Property Name="NeedUnTar">' . $epg_file_set_info['nns_tar']. '</Property>';//文件是否为tar包,0 否,1 是
        $xml_str .= '<Property Name="BeginTime">' . $show_time . '</Property>';//文件生效时间
        $xml_str .= '</Object>';
        //EPGFile
        $xml_str .= '<Object ElementType="EPGFile" ID="' . $epg_file_info['nns_import_id'] . '" Action="' . $action .  '" >';
        $xml_str .= '<Property Name="SourceUrl">' . $epg_file_info['nns_url'] . '</Property>';//模板文件URL,ftp://username:password@ip:port/...  标准FTP协议
        $xml_str .= '<Property Name="DestPath">' . $epg_file_info['nns_dest_path'] . '</Property>';//厂商在EPG Sever 上存储该文件的相对路径。如果是相对路径的根路径，则用空表示。如：epg/bestv/
        $xml_str .= '<Property Name="MD5">' . $epg_file_info['nns_md5'] . '</Property>';//文件生效时间
        $xml_str .= '</Object>';

        $xml_str .= '</Objects>';
        $xml_str .= '</ADI>';

        /*******调用统一注入方法******/

        foreach ($addr_arr as $v)
        {
            $arr = explode('|', $v);//定义格式：address|CSPID|LSPID
            $execute_info = array(
                'nns_task_type' => "EPGFile",
                'nns_action' => $action, //行为动作
                'nns_content' => $xml_str,//注入XML内容
                'nns_addr' => $arr[0],
                'CSPID' => $arr[1],
                'LSPID' => $arr[2],
            );
            $this->execute($execute_info);
        }
        unset($execute_info);

        return $this->write_log_return("C2任务epgfileset执行完毕", NS_CDS_SUCCE);
    }

    /**
     * 主媒资、分集、片源的删除
     * @param string $action
     * @param string $video_type
     * @return array
     */
    private function do_destroy($action = '', $video_type = "video")
    {
        if (!isset($action) && $this->get_c2_info("action") === NS_CDS_DELETE)
        {
            $action = "DELETE";
        }
        $action = isset($action) && strlen($action) > 0 ? strtoupper($action) : "DELETE";

        /*******获取CDN注入ID******/
        $cdn_import_id = $this->get_video_cdn_import_id($video_type);
        if (empty($cdn_import_id))
        {
            return $this->write_log_return("C2任务生成CDN注入ID失败", NS_CDS_FAIL);
        }

        //映射节点类型
        switch ($video_type)
        {
            case "file" :
                $type = "EPGFile";
                break;
            default :
                return $this->write_log_return("C2任务类型错误", NS_CDS_FAIL);
                break;
        }


        $xml_str = '<?xml version="1.0" encoding="UTF-8"?><ADI xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" BizDomain="2" Priority="1">';
        $xml_str .= '<Objects>';
        $xml_str .= '<Object ElementType="' . $type . '" ID="' . $cdn_import_id . '" Action="' . $action . '">';
        $xml_str .= '</Object>';
        $xml_str .= '</Objects>';
        $xml_str .= '</ADI>';
        /*******调用统一注入方法******/
        $execute_info = array(
            'nns_task_type' => $type,//删除操作的媒资类型，主媒资、分集、片源
            'nns_action' => $action, //行为动作
            'nns_content' => $xml_str,//注入XML内容
        );
        return $this->execute($execute_info);
    }


    /**
     * @description:对保存到本地的xml进行解析
     * @author:xinxin.deng
     * @date: 2018/3/6 10:36
     * @param $nns_notify_content
     * @return array
     */
    public function notify_content_to_arr($nns_notify_content)
    {
        \ns_core\m_load::load_np("np_xml2array.class.php");
        //解析下载的XML
        $dom = new DOMDocument('1.0', 'utf-8');
        $dom->loadXML($nns_notify_content);
        $xml = $dom->saveXML();
        $xml_arr = \np_xml2array::getArrayData($xml);
        if ($xml_arr['ret'] != 1)
        {
            return $this->write_log_return("CDN消息反馈的xml解析失败：" . var_export($xml_arr, true), 1);
        }
        $xml_arr = (isset($xml_arr['data']['children'][0]['children'])) ? $xml_arr['data']['children'][0]['children'] : null;
        if (empty($xml_arr) || !is_array($xml_arr))
        {
            return $this->write_log_return('CDN消息反馈的xml解析成功，但是数组有问题:' . var_export($xml_arr, true), 1);
        }
        $result_notify = array();
        foreach ($xml_arr as $k => $v)
        {
            $result_notify[$v['attributes']['Name']] = $v['content'];
        }
        return \m_config::return_data(0, 'ok', $result_notify);
    }
}